import React from 'react';
import { findDOMNode } from 'react-dom';
import $ from 'jquery';
import _ from 'underscore';
import View from 'lib/View.jsx';
import Layout from '../common/layout.jsx';
import Card from 'lib/components/card.jsx';
import jsPlumb from 'local-jsplumb';
import imgSrc from 'lib/util/ImageSource';
import MainScope from './MainScope.es6';
import ApiFactory from 'lib/ApiFactory';
import DefaultLoadingElement from 'lib/util/defaultLoadingElement.jsx';

var toggleServiceApi = ApiFactory({
  method:'post',
  url:function(params){
    return BlueWare.urlPrefix + '/app/' + params.appId + '/updateurlgroup'
  },
  optionParams:['appId'],
  params:{
    appId:{
      defaultValue:BlueWare.appId
    }
  }
});

export default class MainView extends View {
  constructor(props){
    super(props);
    this._connectNode = this._connectNode.bind(this);
  }
  _connectNode(){
    $(window).scrollTop(0)
    var $map = $(this.refs.map)
    this.instance.reset()
    $map.find('.topo-container').each((n1,i) => {
      var $container = $(i)
        , $innerServices = $container.find('.left-area').find('.subject-item')
        , $outerServices = $container.find('.right-area').find('.subject-item')
        , $app = $container.find('.app-item')
        , len = Math.max(1,Math.max($innerServices.length,$outerServices.length))
        , margin = 20
        , subjectWidth = 200
        , subjectHeight = 120
      $container.height(len * (margin + subjectHeight) + margin)
      $innerServices.each((n,subject) => {
        var $this = $(subject)
        this.instance.connect({
          source:$app,
          target:$this
        },{
          connector:'Flowchart',
          paintStyle:{lineWidth:1.5,strokeStyle:'#eee'},
          endpoint:'Blank',
          anchor:['Left','Right']
        });
      })
      $outerServices.each((n,subject) => {
        var $this = $(subject)
        this.instance.connect({
          source:$app,
          target:$this
        },{
          connector:'Flowchart',
          paintStyle:{lineWidth:1.5,strokeStyle:'#eee'},
          endpoint:'Blank',
          anchor:['Right','Left']
        });
      })
    });
    this.instance.repaintEverything()
  }
  setTransactionGroup(tran,newGroup){
    toggleServiceApi({
      domainId:tran.id,
      group:newGroup
    }).post().then((res) => {
      if(res.result){
        tran.group = newGroup
        this.forceUpdate()
      }
    })
  }
  componentDidMount(){
    super.componentDidMount();
    jsPlumb.importDefaults({
      DragOptions : { cursor: 'pointer', zIndex:2000 },
      HoverClass:'connector-hover'
    });
    this.instance = jsPlumb.getInstance({
      Container:this.refs.map
    });
    $(window).add(findDOMNode(this)).on('resize',this._connectNode)
  }
  componentWillUnmount(){
    $(window).add(findDOMNode(this)).off('resize',this._connectNode)
  }
  componentDidUpdate(){
    this._connectNode()
  }
  renderOS(os_views){
    return (
      <div className="app-item" style={{width:160,height:120,marginLeft:-80,marginTop:-45}}>
        <div className="map-app">
          <h4 className="map-app-title">{os_views.name}</h4>
          <img className="map-app-ico" src={
            imgSrc('mi/'+BlueWare.platform.toLowerCase()+'-icon.png')
          }/>
          <p className="data-stuff">
            <span className="label">{os_views.error_rate.label}</span>
            <span className="value">{os_views.error_rate.fmtVal}</span>
          </p>
          <p className="data-stuff">
            <span className="label">{os_views.session_count.label}</span>
            <span className="value">{os_views.session_count.fmtVal}</span>
          </p>
        </div>
      </div>
    )
  }
  renderTransaction(tran,ind){
    var op = null;
    switch (tran.group) {
      case 'IN':
        op = (
          <a href="javascript:;" onClick={this.setTransactionGroup.bind(this,tran,'OUT')}>设为第三方服务</a>
        )
        break;
      case 'OUT':
        op = (
          <a href="javascript:;" onClick={this.setTransactionGroup.bind(this,tran,'IN')}>设为自身服务</a>
        )
        break;
      default:

    }
    let appId = BlueWare.appVersionId ? BlueWare.appVersionId : BlueWare.appId;
    return (
      <div className="subject-item" key={tran.id} style={{width:200,height:120}}>
        <div className="map-app">
          <h4 className="map-app-title">
            <a data-tip={tran.name} data-place="top"
              href={BlueWare.pageUrlPrefix+'/app/'+appId+'/http#/domain/'+tran.id}
            >
              {tran.name}
            </a>
          </h4>
          <p className="data-stuff">
            <span className="label">{tran.avg_resp.label+':'}</span>
            <span className="value">{tran.avg_resp.fmtVal}</span>
          </p>
          <p className="data-stuff">
            <span className="label">{tran.thp.label+':'}</span>
            <span className="value">{tran.thp.fmtVal}</span>
          </p>
        </div>
        <div className="subject-op">
          {op}
        </div>
      </div>
    )
  }
  render(){
    return (
      <Layout title="拓扑" subtitle="展现外部服务调用关系">
        <div ref="map" className="box">
          {
            this.state.loading ? <DefaultLoadingElement /> : (
              <div className="topo-map">
                <div className="topo-container">
                  {
                    this.renderOS(this.state.os_views)
                  }
                  <div className="service-area left-area">
                    <h1>自身服务</h1>
                    {
                      this.state.os_views.transactions.filter((tran,n) => tran.group === 'IN')
                                                      .map(this.renderTransaction,this)
                    }
                  </div>
                  <div className="service-area right-area">
                    <h1>第三方服务</h1>
                    {
                      this.state.os_views.transactions.filter((tran,n) => tran.group === 'OUT')
                                                      .map(this.renderTransaction,this)
                    }
                  </div>
                </div>
              </div>
            )
          }
        </div>
      </Layout>
    )
  }
}
MainView.defaultProps = {
  Scope:MainScope
}
